﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Reviewer.Security;
using System.Web.Security;

using RS = global::Reviewer.Security;

namespace Test.Reviewer.Security
{
    /// <summary>
    // This is a test class for MemebershipProvider and is intended
    ///to contain all MemebershipProvider Unit Tests    
    /// </summary>
    [TestClass]
    public class MemebershipProviderTest
    {
        private TestContext testContextInstance;
        public MemebershipProviderTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void CreateUserTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            string suffix = DateTime.Now.Ticks.ToString();
            Guid providerUserKey = Guid.NewGuid();

            MembershipCreateStatus status;

            MembershipUser user = provider.CreateUser(
                String.Format("TestUser {0}", suffix),
                "pass@word1",
                String.Format("TestUser{0}@domain.int", suffix),
                "question",
                "answer",
                true,
                providerUserKey,
                out status);

            Assert.AreEqual(MembershipCreateStatus.Success, status);
            Assert.IsNotNull(user);
            Assert.AreEqual(providerUserKey, new Guid(user.ProviderUserKey.ToString()));
        }

        [TestMethod()]
        public void DeleteUserTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int totalRecords = 0;
            MembershipUserCollection testUsers = provider.FindUsersByName("TestUser%", 1, 1, out totalRecords);

            Assert.AreNotEqual(0, totalRecords);
            Assert.AreNotEqual(0, testUsers.Count);

            foreach (MembershipUser testUser in testUsers)
            {
                bool success = provider.DeleteUser(testUser.UserName, true);
                Assert.IsTrue(success);
                break;
            }
        }

        [TestMethod]
        public void ChangePasswordTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int totalRecords = 0;
            MembershipUserCollection testUsers = provider.FindUsersByName("TestUser%", 1, 1, out totalRecords);

            Assert.AreNotEqual(0, totalRecords);
            Assert.AreNotEqual(0, testUsers.Count);

            foreach (MembershipUser testUser in testUsers)
            {
                bool success = provider.ChangePassword(testUser.UserName, "pass@word1", "word1@pass");
                Assert.IsTrue(success);
                success = provider.ChangePassword(testUser.UserName, "word1@pass", "pass@word1");
                Assert.IsTrue(success);
                break;
            }
        }

        [TestMethod]
        public void ChangePasswordQuestionAndAnswerTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int totalRecords = 0;
            MembershipUserCollection testUsers = provider.FindUsersByName("TestUser%", 1, 1, out totalRecords);

            Assert.AreNotEqual(0, totalRecords);
            Assert.AreNotEqual(0, testUsers.Count);

            foreach (MembershipUser testUser in testUsers)
            {
                bool success = provider.ChangePasswordQuestionAndAnswer(testUser.UserName, "pass@word1", "answer", "question");
                Assert.IsTrue(success);
                success = provider.ChangePasswordQuestionAndAnswer(testUser.UserName, "pass@word1", "question", "answer");
                Assert.IsTrue(success);
                break;
            }
        }

        [TestMethod]
        public void FindUsersByEmailTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int totalRecords = 0;
            MembershipUserCollection testUsers = provider.FindUsersByEmail("%@domain.int", 1, 1, out totalRecords);

            Assert.AreNotEqual(0, totalRecords);
            Assert.AreNotEqual(0, testUsers.Count);
        }

        [TestMethod]
        public void FindUsersByNameTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int totalRecords = 0;
            MembershipUserCollection testUsers = provider.FindUsersByName("TestUser%", 1, 1, out totalRecords);

            Assert.AreNotEqual(0, totalRecords);
            Assert.AreNotEqual(0, testUsers.Count);
        }

        [TestMethod]
        public void GetAllUsersTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int totalRecords = 0;
            MembershipUserCollection testUsers = provider.GetAllUsers(0, 10, out totalRecords);

            Assert.AreNotEqual(0, totalRecords);
            Assert.AreNotEqual(0, testUsers.Count);
        }

        [TestMethod]
        public void GetNumberOfUsersOnlineTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int usersOnline = provider.GetNumberOfUsersOnline();

            if (usersOnline == 0)
            {
                Assert.Inconclusive();
            }
            else
            {
                Assert.IsTrue(usersOnline > 0);
            }
        }

        [TestMethod]
        public void GetPasswordTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int totalRecords = 0;
            MembershipUserCollection testUsers = provider.FindUsersByName("TestUser%", 1, 1, out totalRecords);

            Assert.AreNotEqual(0, totalRecords);
            Assert.AreNotEqual(0, testUsers.Count);

            foreach (MembershipUser testUser in testUsers)
            {
                string password = provider.GetPassword(testUser.UserName, "answer");
                Assert.AreEqual("pass@word1", password);
                break;
            }
        }

        [TestMethod]
        public void ResetPasswordTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int totalRecords = 0;
            MembershipUserCollection testUsers = provider.FindUsersByName("TestUser%", 1, 1, out totalRecords);

            Assert.AreNotEqual(0, totalRecords);
            Assert.AreNotEqual(0, testUsers.Count);

            foreach (MembershipUser testUser in testUsers)
            {
                string password = provider.ResetPassword(testUser.UserName, "answer");
                Assert.AreNotEqual("pass@word1", password);
                bool success = provider.ChangePassword(testUser.UserName, password, "pass@word1");
                Assert.IsTrue(success);
                break;
            }
        }

        [TestMethod]
        public void ValidateUserTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int totalRecords = 0;
            MembershipUserCollection testUsers = provider.FindUsersByName("TestUser%", 1, 1, out totalRecords);

            Assert.AreNotEqual(0, totalRecords);
            Assert.AreNotEqual(0, testUsers.Count);

            foreach (MembershipUser testUser in testUsers)
            {
                bool success = provider.ValidateUser(testUser.UserName, "thisisnottherightpassword");
                Assert.IsFalse(success);

                success = provider.ValidateUser(testUser.UserName, "pass@word1");
                Assert.IsTrue(success);
                break;
            }
        }

        [TestMethod]
        public void UpdateUserTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int totalRecords = 0;
            MembershipUserCollection testUsers = provider.FindUsersByName("TestUser%", 1, 1, out totalRecords);

            Assert.AreNotEqual(0, totalRecords);
            Assert.AreNotEqual(0, testUsers.Count);

            foreach (MembershipUser testUser in testUsers)
            {
                MembershipUser user = provider.GetUser(testUser.UserName, false);

                string newCommentLine = DateTime.Now.Ticks.ToString();

                user.Comment = newCommentLine;

                provider.UpdateUser(user);

                MembershipUser updatedUser = provider.GetUser(testUser.UserName, false);
                Assert.AreEqual(newCommentLine, updatedUser.Comment);

                break;
            }
        }

        [TestMethod]
        public void UnlockUserTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int totalRecords = 0;
            MembershipUserCollection testUsers = provider.FindUsersByName("TestUser%", 1, 1, out totalRecords);

            Assert.AreNotEqual(0, totalRecords);
            Assert.AreNotEqual(0, testUsers.Count);

            foreach (MembershipUser testUser in testUsers)
            {
                bool success = provider.UnlockUser(testUser.UserName);
                Assert.IsTrue(success);
                break;
            }
        }

        [TestMethod]
        public void GetUserTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int totalRecords = 0;
            MembershipUserCollection testUsers = provider.FindUsersByName("TestUser%", 1, 1, out totalRecords);

            Assert.AreNotEqual(0, totalRecords);
            Assert.AreNotEqual(0, testUsers.Count);

            foreach (MembershipUser testUser in testUsers)
            {
                MembershipUser user1 = provider.GetUser(testUser.UserName, true);
                MembershipUser user2 = provider.GetUser(testUser.ProviderUserKey, true);

                Assert.AreEqual(user1.ProviderUserKey, user2.ProviderUserKey);
                Assert.AreEqual(user1.UserName, user2.UserName);

                break;
            }
        }

        [TestMethod]
        public void GetUserByEmailTest()
        {
            RS.MembershipProvider provider = Membership.Provider as RS.MembershipProvider;

            int totalRecords = 0;
            MembershipUserCollection testUsers = provider.FindUsersByName("TestUser%", 1, 1, out totalRecords);

            Assert.AreNotEqual(0, totalRecords);
            Assert.AreNotEqual(0, testUsers.Count);

            foreach (MembershipUser testUser in testUsers)
            {
                string username = provider.GetUserNameByEmail(testUser.Email);

                Assert.AreEqual(testUser.UserName, username);

                break;
            }
        }
    }
}
